#include<event2/bufferevent.h>
#include<event2/listener.h>
#include<string.h>
#include<stdio.h>
#include<unistd.h>

void readcb(struct bufferevent *bev, void *ctx)
{
    char buf[BUFSIZ];
    int ret = bufferevent_read(bev, buf, sizeof(buf));

    write(STDOUT_FILENO, buf, ret);

    bufferevent_write(bev, "received!\n", strlen("received!\n"));

    sleep(1);
    return;
}

void writecb(struct bufferevent *bev, void *ctx)
{
    printf("Data has been write to client!\n");
}

void eventcb(struct bufferevent *bev, short events, void *arg)
{
    if (events & BEV_EVENT_EOF)
    {
        printf("connection closed\n");  
    }
    else if(events & BEV_EVENT_ERROR)   
    {
        printf("some other error\n");
    }
    
    bufferevent_free(bev);    
    printf("buffevent 资源已经被释放...\n"); 
}

void listener_cb(struct evconnlistener * listener, evutil_socket_t cfd, struct sockaddr *cliaddr, int len, void* ptr)
{
    struct event_base* base = (struct event_base*)ptr;

    struct bufferevent * bev = bufferevent_socket_new(base, cfd, BEV_OPT_CLOSE_ON_FREE);

    bufferevent_setcb(bev, readcb, writecb, eventcb, NULL);

    bufferevent_enable(bev, EV_READ);
    return;
}

int main(int argc, char* argv[])
{
    struct sockaddr_in listenAddr;
    memset(&listenAddr, 0, sizeof(listenAddr));
    listenAddr.sin_family = AF_INET;
    listenAddr.sin_port = htons(8000);

    struct event_base * base = event_base_new();
    struct evconnlistener *listener = evconnlistener_new_bind(base, listener_cb, base, LEV_OPT_CLOSE_ON_FREE|LEV_OPT_REUSEABLE, -1, (struct sockaddr*)&listenAddr, sizeof(listenAddr));

    event_base_dispatch(base);

    evconnlistener_free(listener);
    event_base_free(base);

    return 0;
}